home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-11 | 26.8 KB | 1,128 lines |
- /*
- * File: init.r
- * Initialization, termination, and such.
- * Contents: read_hdr, init/icon_init, envset, env_err, env_int,
- * fpe_trap, inttrag, segvtrap, error, syserr, c_exit, err,
- * fatalerr, pstrnmcmp, datainit, [loadicode, savepstate, loadpstate]
- */
-
- #if !COMPILER
- #include "../h/header.h"
- #endif /* !COMPILER */
-
- /*
- * Prototypes.
- */
-
- hidden novalue env_err Params((char *msg,char *name,char *val));
- FILE *pathOpen Params((char *fname, char *mode));
-
- /*
- * The following code is operating-system dependent [@init.01]. Declarations
- * that are system-dependent.
- */
-
- #if PORT
- /* probably needs something more */
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA
- int chkbreak; /* if nonzero, check for ^C */
- #endif /* AMIGA */
-
- #if MSDOS
- #if HIGHC_386
- int _fmode = 0; /* force CR-LF on std.. files */
- #endif /* HIGHC_386 */
- #endif /* MSDOS */
-
- #if ARM || ATARI_ST || MACINTOSH || MVS || VM || OS2 || UNIX || VMS
- /* nothing needed */
- #endif /* ARM || ATARI_ST || MACINTOSH ... */
-
- /*
- * End of operating-system specific code.
- */
-
- #if !COMPILER
- #ifdef MemMon
- extern char *monfname; /* explicit -E value from iconx cmd */
- #endif /* MemMon */
- #endif /* !COMPILER */
-
- #ifdef IconAlloc
- #define malloc mem_alloc
- #endif /* IconAlloc */
-
- #if !COMPILER
- #define OpDef(p,n,s) int Cat(O,p) Params((dptr cargp));
- #include "../h/odefs.h"
- #undef OpDef
-
- /*
- * External declarations for operator blocks.
- */
-
- #passthru #ifdef MultiThread
- #passthru #define OpDef(f,nargs,sname)\
- {\
- T_Proc,\
- Vsizeof(struct b_proc),\
- Cat(O,f),\
- nargs,\
- -1,\
- 0,\
- 0,\
- 0,\
- {{sizeof(sname)-1,sname}}},
- #passthru #else /* MultiThread */
- #passthru #define OpDef(f,nargs,sname)\
- {\
- T_Proc,\
- Vsizeof(struct b_proc),\
- Cat(O,f),\
- nargs,\
- -1,\
- 0,\
- 0,\
- {{sizeof(sname)-1,sname}}},
- #passthru #endif /* MultiThread */
- #passthru static B_IProc(2) init_op_tbl[] = {
- #passthru #include "../h/odefs.h"
- #passthru };
- #undef OpDef
- #endif /* !COMPILER */
- /*
- * A number of important variables follow.
- */
-
- int line_info; /* flag: line information is available */
- char *file_name = NULL; /* source file for current execution point */
- int line_num = 0; /* line number for current execution point */
- struct b_proc *op_tbl; /* operators available for string invocation */
-
- extern struct errtab errtab[]; /* error numbers and messages */
-
- word mstksize = MStackSize; /* initial size of main stack */
- word stksize = StackSize; /* co-expression stack size */
-
- int k_level = 0; /* &level */
- struct descrip k_main; /* &main */
-
- word statsize = MaxStatSize; /* size of static region */
- word statincr = MaxStatSize/4; /* increment for static region */
- char *statbase = NULL; /* start of static space */
- char *statend; /* end of static space */
- char *statfree; /* static space free pointer */
-
- #ifndef MultiRegion
- word ssize = MaxStrSpace; /* initial string space size (bytes) */
- char *strbase; /* start of string space */
- char *strend; /* end of string space */
- char *strfree; /* string space free pointer */
- #endif /* MultiRegion */
- char *currend = NULL; /* current end of memory region */
-
- #ifndef MultiRegion
- word abrsize = MaxAbrSize; /* initial size of allocated block
- region (bytes) */
- char *blkbase; /* start of block region */
- char *blkend; /* end of allocated blocks */
- char *blkfree; /* block region free pointer */
- #endif /* MultiRegion */
-
- #ifdef FixedRegions
- word qualsize = QualLstSize; /* size of quallist for fixed regions */
- #endif /* FixedRegions */
-
- uword statneed; /* stated need for static space */
- uword strneed; /* stated need for string space */
- uword blkneed; /* stated need for block space */
-
- uword stattotal = 0; /* cumulative total static allocation */
- uword strtotal = 0; /* cumulative total string allocation */
- uword blktotal = 0; /* cumulative total block allocation */
-
- int dodump; /* if nonzero, core dump on error */
- int noerrbuf; /* if nonzero, do not buffer stderr */
-
- struct descrip k_current; /* current expression stack pointer */
- struct descrip maps2; /* second cached argument of map */
- struct descrip maps3; /* third cached argument of map */
-
- int k_errornumber = 0; /* &errornumber */
- char *k_errortext = ""; /* &errortext */
- struct descrip k_errorvalue; /* &errorvalue */
- int have_errval = 0; /* &errorvalue has legal value */
- int t_errornumber = 0; /* tentitive k_errornumber value */
- int t_have_val = 0; /* tentitive have_errval flag */
- struct descrip t_errorvalue; /* tentative k_errorvalue value */
-
- struct b_coexpr *stklist; /* base of co-expression block list */
- dptr argp = NULL; /* argument pointer */
-
- struct tend_desc *tend = NULL; /* chain of tended descriptors */
-
- #ifdef MultiRegion
- struct region rootstring, rootblock;
- #endif /* MultiRegion */
-
- #ifdef MultiRegion
- struct region *curstring, *curblock;
- #endif /* MultiRegion */
-
- #if COMPILER
- struct p_frame *pfp = NULL; /* procedure frame pointer */
-
- struct descrip *globals; /* array of global variables */
- struct descrip *gnames; /* array of names of global variables */
-
- int debug_info; /* flag: is debugging information available */
- int err_conv; /* flag: is error conversion supported */
- int largeints; /* flag: large integers are supported */
-
- struct b_coexpr *mainhead; /* &main */
-
- #else /* COMPILER */
-
- int debug_info=1; /* flag: debugging information IS available */
- int err_conv=1; /* flag: error conversion IS supported */
-
- int op_tbl_sz = (sizeof(init_op_tbl) / sizeof(struct b_proc));
- struct pf_marker *pfp = NULL; /* Procedure frame pointer */
-
- #ifndef MaxHeader
- #define MaxHeader MaxHdr
- #endif /* MaxHeader */
-
-
- struct b_coexpr *mainhead; /* &main */
-
- char *code; /* interpreter code buffer */
- word *records; /* pointer to record procedure blocks */
- word *ftabp; /* pointer to record/field table */
- dptr fnames, efnames; /* pointer to field names */
- dptr globals, eglobals; /* pointer to global variables */
- dptr gnames, egnames; /* pointer to global variable names */
- dptr statics, estatics; /* pointer to static variables */
- char *strcons; /* pointer to string constant table */
- struct ipc_fname *filenms, *efilenms; /* pointer to ipc/file name table */
- struct ipc_line *ilines, *elines; /* pointer to ipc/line number table */
-
- #ifdef TraceBack
- #endif /* TraceBack */
-
-
- #ifdef TallyOpt
- word tallybin[16]; /* counters for tallying */
- int tallyopt = 0; /* want tally results output? */
- #endif /* TallyOpt */
-
- #ifdef ExecImages
- int dumped = 0; /* non-zero if reloaded from dump */
- #endif /* ExecImages */
-
- word *stack; /* Interpreter stack */
- word *stackend; /* End of interpreter stack */
-
-
- #ifdef MultipleRuns
- extern word coexp_ser;
- extern word list_ser;
- extern word set_ser;
- extern word table_ser;
- extern int first_time;
- #endif /* MultipleRuns */
- #endif /* COMPILER */
-
- #if !COMPILER
- /*
- * Open the icode file and read the header.
- * Used by icon_init() as well as MultiThread's loadicode()
- */
- FILE *readhdr(name,hdr)
- char *name;
- struct header *hdr;
- {
- FILE *fname = NULL;
- int n;
-
- if (!name)
- error("no interpreter file supplied");
-
- /*
- * Try adding the suffix if the file name doesn't end in it.
- */
- n = strlen(name);
- if (n <= 4 || (strcmp(name+n-4,IcodeSuffix) != 0)
- && strcmp(name+n-4,IcodeASuffix) != 0) {
- char tname[100];
- if (strlen(name) + 5 > 100)
- error("icode file name too long");
- strcpy(tname,name);
-
- #if MVS
- {
- char *p;
- if (p = index(name, '(')) {
- tname[p-name] = '\0';
- }
- #endif /* MVS */
-
- strcat(tname,IcodeSuffix);
-
- #if MVS
- if (p) strcat(tname,p);
- }
- #endif /* MVS */
-
- #if MSDOS || OS2
- fname = pathOpen(tname,ReadBinary); /* try to find path */
- #else /* MSDOS || OS2 */
- fname = fopen(tname, ReadBinary);
- #endif /* MSDOS || OS2 */
- }
-
- if (fname == NULL) /* try the name as given */
-
- #if MSDOS
- fname = pathOpen(name, ReadBinary);
- #else /* MSDOS */
- fname = fopen(name, ReadBinary);
- #endif /* MSDOS */
-
- if (fname == NULL)
- error("cannot open interpreter file");
-
-
- {
- static char errmsg[] = "can't read interpreter file header";
-
- #ifdef Header
- if (fseek(fname, (long)MaxHeader, 0) == -1)
- error(errmsg);
- #endif /* Header */
-
- if (fread((char *)hdr, sizeof(char), sizeof(*hdr), fname) != sizeof(*hdr))
- error(errmsg);
- }
-
-
- return fname;
- }
- #endif
-
- /*
- * icon_init - initialize memory and prepare for Icon execution.
- */
-
- #if COMPILER
- novalue init(name, trc_init)
- char *name;
- int trc_init;
- #else /* COMPILER */
- novalue icon_init(name)
- char *name;
- #endif /* COMPILER */
-
- {
- int n;
- #if !COMPILER
- struct header hdr;
- FILE *fname = NULL;
- word cbread, longread();
- #endif /* COMPILER */
-
- #if COMPILER
- #ifdef MultiRegion
- curstring = &rootstring;
- curblock = &rootblock;
- rootstring.size = MaxStrSpace;
- rootblock.size = MaxAbrSize;
- #endif /* MultiRegion */
- #else /* COMPILER */
-
-
- #ifdef MultiRegion
- curstring = &rootstring;
- curblock = &rootblock;
- #endif /* MultiRegion */
-
- #ifdef MultiRegion
- rootstring.size = MaxStrSpace;
- rootblock.size = MaxAbrSize;
- #endif /* MultiRegion */
- #endif /* COMPILER */
-
- #if !COMPILER
- op_tbl = (struct b_proc*)init_op_tbl;
- #endif /* !COMPILER */
-
- /*
- * Catch floating-point traps and memory faults.
- */
-
- /*
- * The following code is operating-system dependent [@init.02]. Set traps.
- */
-
- #if PORT
- /* probably needs something */
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA
- signal(SIGFPE,fpetrap);
- #endif /* AMIGA */
-
- #if ARM
- signal(SIGFPE, (void (*)(int))fpetrap);
- signal(SIGSEGV, (void (*)(int))segvtrap);
- #endif /* ARM */
-
- #if ATARI_ST
- #endif /* ATARI_ST */
-
- #if MACINTOSH
- #if MPW
- /* This is equivalent to SIGFPE signal in the Standard Apple
- Numeric Environment (SANE) */
- {
- environment e;
- getenvironment(&e);
- #ifdef mc68881
- e.FPCR |= CURUNDERFLOW|CUROVERFLOW|CURDIVBYZERO;
- #else /* mc68881 */
- e |= UNDERFLOW|OVERFLOW|DIVBYZERO;
- #endif /* mc68881 */
- setenvironment(e);
- #ifdef mc68881
- {
- static trapvector tv =
- {fpetrap,fpetrap,fpetrap,fpetrap,fpetrap,fpetrap,fpetrap};
- settrapvector(&tv);
- }
- #else /* mc6881 */
- sethaltvector((haltvector)fpetrap);
- #endif /* mc6881 */
- }
- #endif /* MPW */
- #endif /* MACINTOSH */
-
- #if MSDOS
- #if LATTICE || MICROSOFT || TURBO
- signal(SIGFPE, fpetrap);
- #endif /* LATTICE || MICROSOFT || TURBO */
- #endif /* MSDOS */
-
- #if MVS || VM
- #if SASC
- cosignal(SIGFPE, fpetrap); /* catch in all coprocs */
- cosignal(SIGSEGV, segvtrap);
- #endif /* SASC */
- #endif /* MVS || VM */
-
- #if OS2
- signal(SIGFPE, fpetrap);
- signal(SIGSEGV, segvtrap);
- #endif /* OS2 */
-
- #if UNIX || VMS
- signal(SIGSEGV, segvtrap);
- #ifdef PYRAMID
- {
- struct sigvec a;
-
- a.sv_handler = fpetrap;
- a.sv_mask = 0;
- a.sv_onstack = 0;
- sigvec(SIGFPE, &a, 0);
- sigsetmask(1 << SIGFPE);
- }
- #else /* PYRAMID */
- signal(SIGFPE, fpetrap);
- #endif /* PYRAMID */
- #endif /* UNIX || VMS */
-
- /*
- * End of operating-system specific code.
- */
-
- #if !COMPILER
- #ifdef ExecImages
- /*
- * If reloading from a dumped out executable, skip most of init and
- * just set up the buffer for stderr and do the timing initializations.
- */
- if (dumped)
- goto btinit;
- #endif /* ExecImages */
- #endif /* COMPILER */
-
- /*
- * Initialize data that can't be initialized statically.
- */
-
- datainit();
-
- #if COMPILER
- IntVal(kywd_trc) = trc_init;
- #endif /* COMPILER */
-
- #if !COMPILER
- fname = readhdr(name,&hdr);
-
- k_trace = hdr.trace;
-
- #endif /* COMPILER */
-
- #ifdef EnvVars
- /*
- * Examine the environment and make appropriate settings. [[I?]]
- */
- envset();
- #endif /* EnvVars */
-
-
- /*
- * Convert stack sizes from words to bytes.
- */
-
- #ifndef SCO_XENIX
- stksize *= WordSize;
- mstksize *= WordSize;
- #else /* SCO_XENIX */
- /*
- * This is a work-around for bad generated code for *= (as above)
- * produced by the SCO XENIX C Compiler for the large memory model.
- * It relies on the fact that WordSize is 4.
- */
- stksize += stksize;
- stksize += stksize;
- mstksize += mstksize;
- mstksize += mstksize;
- #endif /* SCO_XENIX */
-
- #if IntBits == 16
- if (mstksize > MaxBlock)
- fatalerr(316, NULL);
- if (stksize > MaxBlock)
- fatalerr(318, NULL);
- #endif /* IntBits == 16 */
-
- /*
- * Allocate memory for various regions.
- */
- #if COMPILER
- initalloc();
- #else /* COMPILER */
- initalloc(hdr.hsize);
- #endif /* COMPILER */
-
- #if !COMPILER
- /*
- * Establish pointers to icode data regions. [[I?]]
- */
-
- records = (word *)(code + hdr.records);
- ftabp = (word *)(code + hdr.ftab);
- fnames = (dptr)(code + hdr.fnames);
- globals = efnames = (dptr)(code + hdr.globals);
- gnames = eglobals = (dptr)(code + hdr.gnames);
- statics = egnames = (dptr)(code + hdr.statics);
- estatics = (dptr)(code + hdr.filenms);
- n_globals = eglobals - globals;
- n_statics = estatics - statics;
- filenms = (struct ipc_fname *)estatics;
- efilenms = (struct ipc_fname *)(code + hdr.linenums);
- ilines = (struct ipc_line *)efilenms;
- elines = (struct ipc_line *)(code + hdr.strcons);
- strcons = (char *)elines;
- #endif /* COMPILER */
-
- /*
- * Allocate stack and initialize &main.
- */
-
- #if COMPILER
- mainhead = (struct b_coexpr *)malloc((msize)sizeof(struct b_coexpr));
- #else /* COMPILER */
- stack = (word *)malloc((msize)mstksize);
- mainhead = (struct b_coexpr *)stack;
-
- #ifndef FixedRegions
- stattotal -= mstksize; /* keep &allocations consistent with &storage */
- #endif /* FixedRegions */
- #endif /* COMPILER */
-
- if (mainhead == NULL)
- #if COMPILER
- err_msg(305, NULL);
- #else /* COMPILER */
- fatalerr(303, NULL);
- #endif /* COMPILER */
-
- mainhead->title = T_Coexpr;
- mainhead->id = 1;
- mainhead->size = 1; /* pretend main() does an activation */
- mainhead->nextstk = NULL;
- mainhead->es_tend = NULL;
- mainhead->freshblk = nulldesc; /* &main has no refresh block. */
- /* This really is a bug. */
- #if COMPILER
- mainhead->file_name = "";
- mainhead->line_num = 0;
- #endif /* COMPILER */
-
- #ifdef Coexpr
- Protect(mainhead->es_actstk = alcactiv(), fatalerr(0,NULL));
- pushact(mainhead, mainhead);
- #endif /* Coexpr */
-
- /*
- * Point &main at the co-expression block for the main procedure and set
- * k_current, the pointer to the current co-expression, to &main.
- */
- k_main.dword = D_Coexpr;
- BlkLoc(k_main) = (union block *) mainhead;
- k_current = k_main;
-
- #if !COMPILER
- /*
- * Read the interpretable code and data into memory.
- */
-
- if ((cbread = longread(code, sizeof(char), (long)hdr.hsize, fname)) !=
- hdr.hsize) {
- fprintf(stderr,"Tried to read %ld bytes of code, got %ld\n",
- (long)hdr.hsize,(long)cbread);
- error("can't read interpreter code");
- }
- fclose(fname);
-
- /*
- * Make sure the version number of the icode matches the interpreter version.
- */
-
- if (strcmp((char *)hdr.config,IVersion)) {
- fprintf(stderr,"icode version mismatch\n");
- fprintf(stderr,"\ticode version: %s\n",(char *)hdr.config);
- fprintf(stderr,"\texpected version: %s\n",IVersion);
- error("cannot run");
- }
- #endif /* !COMPILER */
-
- /*
- * Initialize the event monitoring system, if configured.
- */
-
- #ifdef MemMon
- #if COMPILER
- EVInit(name,NULL);
- #else /* COMPILER */
- EVInit(name,monfname);
- #endif /* COMPILER */
- #endif /* MemMon */
-
- #if !COMPILER
- /*
- * Resolve references from icode to run-time system.
- */
- resolve();
- #endif /* COMPILER */
-
- #ifdef MemMon
- EVSetup();
- #endif /* MemMon */
-
- #if !COMPILER
- #ifdef ExecImages
- btinit:
- #endif /* ExecImages */
- #endif /* COMPILER */
-
- /*
- * The following code is operating-system dependent [@init.03]. Allocate and
- * assign a buffer to stderr if possible.
- */
-
- #if PORT
- /* probably nothing */
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA || MVS || VM
- /* not done */
- #endif /* AMIGA */
-
- #if ARM || ATARI_ST || MACINTOSH || UNIX || OS2 || VMS
-
-
- if (noerrbuf)
- setbuf(stderr, NULL);
- else {
- char *buf;
-
- buf = (char *)malloc((msize)BUFSIZ);
- if (buf == NULL)
- fatalerr(305, NULL);
- setbuf(stderr, buf);
- }
- #endif /* ARM || ATARI_ST || MACINTOSH ... */
-
- #if MSDOS
- #if !HIGHC_386
- if (noerrbuf)
- setbuf(stderr, NULL);
- else {
- char *buf;
-
- buf = (char *)malloc((msize)BUFSIZ);
- if (buf == NULL)
- fatalerr(305, NULL);
- setbuf(stderr, buf);
- }
- #endif /* !HIGHC_386 */
- #endif /* MSDOS */
-
- /*
- * End of operating-system specific code.
- */
-
-
- /*
- * Start timing execution.
- */
-
- millisec();
- }
-
- /*
- * Service routines related to getting things started.
- */
-
-
- #ifdef EnvVars
- /*
- * Check for environment variables that Icon uses and set system
- * values as is appropriate.
- */
- novalue envset()
- {
- register char *p;
-
- if ((p = getenv("NOERRBUF")) != NULL)
- noerrbuf++;
- env_int(TRACE, &k_trace, 0, (uword)0);
- env_int(COEXPSIZE, &stksize, 1, (uword)MaxUnsigned);
- env_int(STRSIZE, &ssize, 1, (uword)MaxBlock);
- env_int(HEAPSIZE, &abrsize, 1, (uword)MaxBlock);
- env_int(BLOCKSIZE, &abrsize, 1, (uword)MaxBlock); /* synonym */
- env_int(BLKSIZE, &abrsize, 1, (uword)MaxBlock); /* synonym */
- env_int(STATSIZE, &statsize, 1, (uword)MaxBlock);
- env_int(STATINCR, &statincr, 1, (uword)MaxBlock);
- env_int(MSTKSIZE, &mstksize, 1, (uword)MaxUnsigned);
-
- #ifdef FixedRegions
- env_int(QLSIZE, &qualsize, 1, (uword)MaxBlock);
- #endif /* FixedRegions */
-
- /*
- * The following code is operating-system dependent [@init.04]. Check any
- * system-dependent environment variables.
- */
-
- #if PORT
- /* nothing to do */
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA
- if ((p = getenv("CHECKBREAK")) != NULL)
- chkbreak++;
- #endif /* AMIGA */
-
- #if ARM || ATARI_ST || MACINTOSH || MSDOS || MVS || OS2 || UNIX || VM
- /* nothing to do */
- #endif /* ARM || ATARI_ST || ... */
-
- #if VMS
- {
- extern word memsize;
- env_int("MAXMEM", &memsize, 1, MaxBlock);
- }
- #endif /* VMS */
-
- /*
- * End of operating-system specific code.
- */
-
- if ((p = getenv(ICONCORE)) != NULL && *p != '\0') {
-
- /*
- * The following code is operating-system dependent [@init.05]. Set trap to
- * give dump on abnormal termination if ICONCORE is set.
- */
-
- #if PORT
- /* can't handle */
- Deliberate Syntax Error
- #endif /* PORT */
-
- #if AMIGA || ATARI_ST || MACINTOSH
- /* can't handle */
- #endif /* AMIGA || ATARI_ST || ... */
-
- #if ARM || OS2
- signal(SIGSEGV, SIG_DFL);
- signal(SIGFPE, SIG_DFL);
- #endif /* ARM || OS2 */
-
- #if MSDOS
- #if LATTICE || TURBO
- signal(SIGFPE, SIG_DFL);
- #endif /* LATTICE || TURBO */
- #endif /* MSDOS */
-
- #if MVS || VM
- /* Really nothing to do. */
- #endif /* MVS || VM */
-
- #if UNIX || VMS
- signal(SIGSEGV, SIG_DFL);
- #endif /* UNIX || VMS */
-
- /*
- * End of operating-system specific code.
- */
- dodump++;
- }
- }
-
- /*
- * env_err - print an error mesage about the value of an environment
- * variable.
- */
- static novalue env_err(msg, name, val)
- char *msg;
- char *name;
- char *val;
- {
- char msg_buf[100];
-
- strncpy(msg_buf, msg, 99);
- strncat(msg_buf, ": ", 99 - (int)strlen(msg_buf));
- strncat(msg_buf, name, 99 - (int)strlen(msg_buf));
- strncat(msg_buf, "=", 99 - (int)strlen(msg_buf));
- strncat(msg_buf, val, 99 - (int)strlen(msg_buf));
- error(msg_buf);
- }
-
- /*
- * env_int - get the value of an integer-valued environment variable.
- */
- novalue env_int(name, variable, non_neg, limit)
- char *name;
- word *variable;
- int non_neg;
- uword limit;
- {
- char *value;
- char *s;
- register uword n = 0;
- register uword d;
- int sign = 1;
-
- if ((value = getenv(name)) == NULL || *value == '\0')
- return;
-
- s = value;
- if (*s == '-') {
- if (non_neg)
- env_err("environment variable out of range", name, value);
- sign = -1;
- ++s;
- }
- else if (*s == '+')
- ++s;
- while (isdigit(*s)) {
- d = *s++ - '0';
- /*
- * See if 10 * n + d > limit, but do it so there can be no overflow.
- */
- if ((d > (uword)(limit / 10 - n) * 10 + limit % 10) && (limit > 0))
- env_err("environment variable out of range", name, value);
- n = n * 10 + d;
- }
- if (*s != '\0')
- env_err("environment variable not numeric", name, value);
- *variable = sign * n;
- }
- #endif /* EnvVars */
-
- /*
- * Termination routines.
- */
-
- /*
- * Produce run-time error 204 on floating-point traps.
- */
-
- novalue fpetrap()
- {
- fatalerr(204, NULL);
- }
-
- /*
- * Produce run-time error 320 on ^C interrupts. Not used at present,
- * since malfunction may occur during traceback.
- */
- novalue inttrap()
- {
- fatalerr(320, NULL);
- }
-
- /*
- * Produce run-time error 302 on segmentation faults.
- */
- novalue segvtrap()
- {
- fatalerr(302, NULL);
- }
-
- /*
- * error - print error message s; used only in startup code.
- */
- novalue error(s)
- char *s;
- {
-
-
- fprintf(stderr, "error in startup code\n%s\n", s);
-
- fflush(stderr);
- if (dodump)
- abort();
- c_exit(ErrorExit);
- }
-
- /*
- * syserr - print s as a system error.
- */
- novalue syserr(s)
- char *s;
- {
-
-
- #if COMPILER
- if (pfp != 0 && line_info)
- fprintf(stderr, "System error at line %d in %s\n%s\n",
- line_num, file_name, s);
- #else /* COMPILER */
- if (pfp != 0)
- fprintf(stderr, "System error at line %ld in %s\n%s\n",
- (long)findline(ipc.opnd), findfile(ipc.opnd), s);
- #endif /* COMPILER */
-
- else
- fprintf(stderr, "System error in startup code\n%s\n", s);
-
- fflush(stderr);
- if (dodump)
- abort();
- c_exit(ErrorExit);
- }
-
- /*
- * c_exit(i) - flush all buffers and exit with status i.
- */
- novalue c_exit(i)
- int i;
- {
- #ifdef EventMon
- EVVal((word)i,E_Exit);
- #endif /* EventMon */
-
- #ifdef MemMon
- EVTerm(0, i == NormalExit ? "Normal Exit" : "Error Exit");
- #endif /* MemMon */
-
- #ifdef TallyOpt
- {
- int j;
-
- if (tallyopt) {
- fprintf(stderr,"tallies: ");
- for (j=0; j<16; j++)
- fprintf(stderr," %ld", (long)tallybin[j]);
- fprintf(stderr,"\n");
- }
- }
- #endif /* TallyOpt */
-
-
- #ifdef MultipleRuns
- /*
- * Free allocated memory so application can continue.
- */
-
- xmfree();
- #endif /* MultipleRuns */
-
- #if TURBO
- flushall();
- _exit(i);
- #else /* TURBO */
- exit(i);
- #endif /* TURBO */
-
- }
-
- /*
- * err() is called if an erroneous situation occurs in the virtual
- * machine code. It is typed as int to avoid declaration problems
- * elsewhere.
- */
- int err()
- {
- syserr("call to 'err'\n");
- return 1; /* unreachable; make compilers happy */
- }
-
- /*
- * fatalerr - disable error conversion and call run-time error routine.
- */
- novalue fatalerr(n, v)
- int n;
- dptr v;
- {
- IntVal(kywd_err) = 0;
- err_msg(n, v);
- }
-
- /*
- * pstrnmcmp - compare names in two pstrnm structs; used for qsort.
- */
- int pstrnmcmp(a,b)
- struct pstrnm *a, *b;
- {
- return strcmp(a->pstrep, b->pstrep);
- }
-
- /*
- * datainit - initialize some global variables.
- */
- novalue datainit()
- {
-
- /*
- * Initializations that cannot be performed statically (at least for
- * some compilers). [[I?]]
- */
-
- k_errout.fd = stderr;
- StrLen(k_errout.fname) = 7;
- StrLoc(k_errout.fname) = "&errout";
- k_errout.status = Fs_Write;
-
- k_input.fd = stdin;
- StrLen(k_input.fname) = 6;
- StrLoc(k_input.fname) = "&input";
- k_input.status = Fs_Read;
-
- k_output.fd = stdout;
- StrLen(k_output.fname) = 7;
- StrLoc(k_output.fname) = "&output";
- k_output.status = Fs_Write;
-
- IntVal(kywd_pos) = 1;
- IntVal(kywd_ran) = 0;
- StrLen(k_subject) = 0;
- StrLoc(k_subject) = "";
-
-
- StrLen(blank) = 1;
- StrLoc(blank) = " ";
- StrLen(emptystr) = 0;
- StrLoc(emptystr) = "";
- BlkLoc(nullptr) = (union block *)NULL;
- BlkLoc(errout) = (union block *) &k_errout;
- BlkLoc(input) = (union block *) &k_input;
- StrLen(lcase) = 26;
- StrLoc(lcase) = "abcdefghijklmnopqrstuvwxyz";
- StrLen(letr) = 1;
- StrLoc(letr) = "r";
- IntVal(nulldesc) = 0;
- k_errorvalue = nulldesc;
- IntVal(onedesc) = 1;
- StrLen(ucase) = 26;
- StrLoc(ucase) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- IntVal(zerodesc) = 0;
-
- maps2 = nulldesc;
- maps3 = nulldesc;
-
- #if !COMPILER
- #if TURBO
- qsort(pntab,pnsize,sizeof(struct pstrnm),
- (int(*)(const void *, const void *))pstrnmcmp);
- #else /* TURBO */
- qsort((char *)pntab,pnsize,sizeof(struct pstrnm),pstrnmcmp);
- #endif /* TURBO */
-
- #ifdef MultipleRuns
- /*
- * Initializations required for repeated program runs
- */
- /* In this module: */
- k_level = 0; /* &level */
- k_errornumber = 0; /* &errornumber */
- k_errortext = ""; /* &errortext */
- statsize = MaxStatSize; /* size of static region */
- statincr = MaxStatSize/4; /* increment for static region */
- statbase = NULL; /* start of static space */
- currend = NULL; /* current end of memory region */
-
-
- mstksize = MStackSize; /* initial size of main stack */
- stksize = StackSize; /* co-expression stack size */
- ssize = MaxStrSpace; /* initial string space size (bytes) */
- abrsize = MaxAbrSize; /* initial size of allocated block
- region (bytes) */
- #ifdef FixedRegions
- qualsize = QualLstSize; /* size of quallist for fixed regions */
- #endif /* FixedRegions */
-
- dodump = 0; /* produce dump on error */
-
- #ifdef ExecImages
- dumped = 0; /* This is a dumped image. */
- #endif /* ExecImages */
-
- /* In module interp.c: */
- pfp = 0; /* Procedure frame pointer */
- sp = NULL; /* Stack pointer */
-
-
- /* In module rmemmgt.c: */
- coexp_ser = 2;
- list_ser = 1;
- set_ser = 1;
- table_ser = 1;
-
- coll_stat = 0;
- coll_str = 0;
- coll_blk = 0;
- coll_tot = 0;
-
- /* In module time.c: */
- first_time = 1;
-
-
- #endif /* MultipleRuns */
- #endif /* COMPILER */
-
- }
-
-